<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  <title>CoffeeScript Test Suite</title>
  <script nomodule src="browser-compiler-legacy/coffeescript.js"></script>
  <script type="module">
    import CoffeeScript from './browser-compiler-modern/coffeescript.js';
    window.CoffeeScript = CoffeeScript;
    window.addEventListener('DOMContentLoaded', CoffeeScript.runScripts, false);
  </script>
  <script src="https://cdn.jsdelivr.net/underscorejs/1.8.3/underscore-min.js"></script>
  <style>
    body, pre {
      font-family: Consolas, Menlo, Monaco, monospace;
    }
    body {
      margin: 1em;
    }
    h1 {
      font-size: 1.3em;
    }
    div {
      margin: 0.6em;
    }
    .good {
      color: #22b24c
    }
    .bad {
      color: #eb6864
    }
    .subtle {
      font-size: 0.7em;
      color: #999999
    }
  </style>
</head>
<body>

<h1>CoffeeScript Test Suite</h1>

<pre id="stdout"></pre>

<script type="text/coffeescript">
@testingBrowser = yes
@global = window
@bold = @red = @green = @reset = ''
stdout = document.getElementById 'stdout'
start = new Date
@currentFile = ''
@passedTests = failedTests = total = done = 0

say = (msg, className, id) ->
  div = document.createElement 'div'
  div.className = className if className?
  div.id = id if id?
  div.appendChild document.createTextNode msg
  stdout.appendChild div
  msg

asyncTests = []
onFail = (description, fn, err) ->
  failures.push
    error: err
    description: description
    source: fn.toString() if fn.toString?

@test = (description, fn) ->
  ++total
  try
    result = fn.call(fn)
    if result instanceof Promise # An async test.
      asyncTests.push result
      result.then ->
        passedTests++
      .catch (err) ->
        onFail description, fn, err
    else
      passedTests++
  catch err
    onFail description, fn, err

@failures =
  push: (failure) -> # Match function called by regular tests
    ++failedTests
    say "#{failure.description}:", 'bad'
    say failure.source, 'subtle' if failure.source?
    say failure.error, 'bad'
    console.error failure.error

@ok = (good, msg = 'Error') ->
  throw Error msg unless good

# Polyfill Node assert’s fail
@fail = ->
  ok no

# Polyfill Node assert’s deepEqual with Underscore’s isEqual
@deepEqual = (a, b) ->
  ok _.isEqual(a, b), "Expected #{JSON.stringify a} to deep equal #{JSON.stringify b}"

<%= testHelpers %>

@doesNotThrow = (fn) ->
  fn()
  ok yes

@throws = (fun, err, msg) ->
  try
    fun()
  catch e
    if err
      if typeof err is 'function' and e instanceof err # Handle comparing exceptions
        ok yes
      else if e.toString().indexOf('[stdin]') is 0 # Handle comparing error messages
        ok err e
      else if err instanceof RegExp
        ok err.test e
      else
        eq e, err
    else
      ok yes
    return
  ok no


# Run the tests
for test in document.getElementsByClassName 'test'
  say '\u2714 ' + test.id
  options = {}
  options.filename = currentFile = test.id
  options.literate = yes if test.type is 'text/x-literate-coffeescript'
  CoffeeScript.run test.innerHTML, options

# Finish up
done = ->
  yay = passedTests is total and not failedTests
  sec = (new Date - start) / 1000
  msg = "passed #{passedTests} tests in #{sec.toFixed 2} seconds"
  msg = "failed #{total - passedTests} tests and #{msg}" unless yay
  say msg, (if yay then 'good' else 'bad'), 'result'

  gtag 'event', 'tests_complete',
    event_category: 'tests'
    event_label: if yay then 'passed' else 'failed'
    value: if yay then passedTests else total - passedTests
  gtag 'event', 'tests_report',
    event_category: 'tests'
    event_label: msg
  gtag 'event', 'timing_complete',
    name: 'tests_run'
    value: sec * 1000

Promise.all(asyncTests).then(done).catch(done)
</script>

<%= tests %>

<script async src="https://www.googletagmanager.com/gtag/js?id=UA-106156830-1"></script>
<script>
  window.GA_TRACKING_ID = 'UA-106156830-1';
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments)};
  gtag('js', new Date());
  gtag('config', GA_TRACKING_ID);
</script>
</body>
</html>
